package com.wdcg.model.access;

import java.sql.SQLException;
import java.util.ArrayList;

import android.util.Log;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.wdcg.model.dao.Dwarf;
import com.wdcg.model.dao.DwarfDescription;
import com.wdcg.model.dao.PlayerLocale;
import com.wdcg.model.dbhelper.DatabaseHelper;

public class DwarfAccess {

	public static ArrayList<DwarfDescription> getDwarvesDescriptions(){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfDescQB.join(dwarfQB);
			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}

		Log.i("getDwarvesDescriptions()",
				"method executed successfully, result=" + result.size());
		return result;
	}

	public static ArrayList<DwarfDescription> getVisibleDwarvesDescriptions(boolean visible){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfQB.where().eq(Dwarf.DWARF_IS_VISIBLE_COLUMN, visible);
			dwarfDescQB.join(dwarfQB);
			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}

		Log.i("getVisibleDwarvesDescriptions()",
				"method executed successfully, result=" + result.size());
		return result;
	}

	public static ArrayList<DwarfDescription> getUnlockedDwarvesDescriptions(boolean unlocked){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfQB.where().eq(Dwarf.DWARF_IS_UNLOCKED_COLUMN, unlocked);
			dwarfDescQB.join(dwarfQB);
			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}

		Log.i("getUnlockedDwarvesDescriptions()",
				"method executed successfully, result=" + result.size());
		return result;
	}

	public static DwarfDescription getDwarfDescriptionForDwarfId(Integer dwarfID){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfQB.where().eq(Dwarf.DWARF_ID_COLUMN, dwarfID);
			dwarfDescQB.join(dwarfQB);
			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}
		if(result!=null){
			if(result.size()>0){
				Log.i("getUnlockedDwarvesDescriptions()",
						"method executed successfully, result=" + result.size());
				return result.get(0);
			}
		}

		return null;

	}

	public static ArrayList<DwarfDescription> getWaitingForPlayDwarvesDescriptions(boolean isWaitingForPlay){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfQB.where().eq(Dwarf.DWARF_IS_WAITING_FOR_PLAY_COLUMN, isWaitingForPlay);
			dwarfDescQB.join(dwarfQB);
			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}

		Log.i("getUnlockedDwarvesDescriptions()",
				"method executed successfully, result=" + result.size());
		return result;
	}

	public static void setDwarfGameScore(Dwarf dwarf, boolean isUnlocked, boolean isWaitingForPlay, boolean isVisible){
		dwarf.setIsUnlocked(isUnlocked);
		dwarf.setIsVisible(isVisible);
		dwarf.setIsWaitingForPlay(isWaitingForPlay);

		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();
		try {
			dbh.getDwarfDao().update(dwarf);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static Dwarf setRandomDwarfAsVisible(){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<Dwarf> possibleDwarves;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		Where<Dwarf, Integer> where = dwarfQB.where();
		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();

			Where<Dwarf, Integer> and = where.and(where.eq(Dwarf.DWARF_IS_WAITING_FOR_PLAY_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_VISIBLE_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_UNLOCKED_COLUMN, false));

			possibleDwarves = (ArrayList<Dwarf>) dwarfQB.query();
		} catch (Exception e1) {
			possibleDwarves = null;
			e1.printStackTrace();
		}
		Dwarf result =null;
		if(possibleDwarves!=null && possibleDwarves.size()>0){
			result=possibleDwarves.get((int)(Math.random()*(possibleDwarves.size()-1)));
		}

		DwarfAccess.setDwarfGameScore(result, false, false, true);
		return result;
	}

	public static void setNRandomDwarfAsVisible(int n){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<Dwarf> possibleDwarves;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		Where<Dwarf, Integer> where = dwarfQB.where();
		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();

			Where<Dwarf, Integer> and = where.and(where.eq(Dwarf.DWARF_IS_WAITING_FOR_PLAY_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_VISIBLE_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_UNLOCKED_COLUMN, false));

			possibleDwarves = (ArrayList<Dwarf>) dwarfQB.query();
		} catch (Exception e1) {
			possibleDwarves = null;
			e1.printStackTrace();
		}
		Dwarf result =null;
		while(possibleDwarves!=null && possibleDwarves.size()>0 && n>0){
			int index=(int)(Math.random()*(possibleDwarves.size()-1));
			result=possibleDwarves.get(index);
			possibleDwarves.remove(index);
			DwarfAccess.setDwarfGameScore(result, false, false, true);
			n--;
		}

	}

	public static void setNRandomDwarfsAsInvisible(int n) {
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<Dwarf> possibleDwarves;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		Where<Dwarf, Integer> where = dwarfQB.where();
		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();

			Where<Dwarf, Integer> and = where.and(where.eq(Dwarf.DWARF_IS_WAITING_FOR_PLAY_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_VISIBLE_COLUMN, true),
					where.eq(Dwarf.DWARF_IS_UNLOCKED_COLUMN, false));

			possibleDwarves = (ArrayList<Dwarf>) dwarfQB.query();
		} catch (Exception e1) {
			possibleDwarves = null;
			e1.printStackTrace();
		}
		Dwarf result =null;
		while(possibleDwarves!=null && possibleDwarves.size()>1 && n>0){
			int index=(int)(Math.random()*(possibleDwarves.size()-1));
			result=possibleDwarves.get(index);
			possibleDwarves.remove(index);
			DwarfAccess.setDwarfGameScore(result, false, false, false);
			n--;
		}

	}


	public static ArrayList<DwarfDescription> getRandomDwarvsForQuiz(int count, Dwarf dwarfToExclude){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> result;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();
		Where<Dwarf, Integer> where = dwarfQB.where();

		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();

			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			dwarfQB.where().not().eq(Dwarf.DWARF_ID_COLUMN,
					dwarfToExclude.getId());

			dwarfDescQB.join(dwarfQB);
			Log.i("query",""+dwarfDescQB.toString());

			result = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			result = new ArrayList<DwarfDescription>();
			e1.printStackTrace();
		}

		Log.i("size",""+result.size());
		ArrayList<DwarfDescription> dwarvesDesc=new ArrayList<DwarfDescription>(result);
		ArrayList<DwarfDescription> randomDwarves=new ArrayList<DwarfDescription>();

		while(randomDwarves.size()<count){
			int random = (int) (Math.random()*dwarvesDesc.size());
			randomDwarves.add(dwarvesDesc.get(random));
			dwarvesDesc.remove(random);
		} 

		Log.i("getDwarvesDescriptions()",
				"method executed successfully, result=" + result.size());
		return randomDwarves;
	}

	public static ArrayList<DwarfDescription> getLockedAndInvisibleDwarfsDescription(){
		DatabaseHelper dbh=DatabaseHelper.getMainDBHelper();

		ArrayList<DwarfDescription> possibleDwarves;
		QueryBuilder<Dwarf, Integer> dwarfQB = dbh.getDwarfDao().queryBuilder();
		QueryBuilder<DwarfDescription, Integer> dwarfDescQB = dbh.getDwarfDescriptionDao().queryBuilder();
		Where<Dwarf, Integer> where = dwarfQB.where();
		try {
			PlayerLocale userLang = LocaleAccess.getCurrUserLocale();
			dwarfDescQB.where().eq(PlayerLocale.LOCALE_ID_COLUMN,
					userLang.getId());
			Where<Dwarf, Integer> and = where.and(where.eq(Dwarf.DWARF_IS_WAITING_FOR_PLAY_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_VISIBLE_COLUMN, false),
					where.eq(Dwarf.DWARF_IS_UNLOCKED_COLUMN, false));
			dwarfDescQB.join(dwarfQB);
			possibleDwarves = (ArrayList<DwarfDescription>) dwarfDescQB.query();
		} catch (Exception e1) {
			possibleDwarves = null;
			e1.printStackTrace();
		}

		return possibleDwarves;
	}

}

